package com.acme.bankapp.domain.bank;

import com.acme.bankapp.domain.bank.exceptions.ClientExistsException;
import com.acme.bankapp.service.bank.EmailService;

import java.io.Serializable;
import java.util.*;

/**
 * Created by anton on 8/18/14.
 */
public class Bank implements Serializable {
    private HashMap<String,Client> clients = new HashMap<>(); //new Client[maxClients];
    private ClientRegistrationListener[] listeners;
    private DebugListener debugListener = null;
    private EmailService emailService;

    // Constructor
    public Bank() {
        this.debugListener = new DebugListener();
        this.listeners = new ClientRegistrationListener[]{new EmailNotificationListener(), new PrintClientListener(), };
        this.emailService = new EmailService();
    }

    public Collection<Client> getClients() {
        return Collections.unmodifiableCollection(clients.values());
    }

    public Client getClientByName(String name) {
        return clients.get(name);
    }

    public int getNbOfClients() {
        return clients.size();
    }

    public void addClient(Client client) throws ClientExistsException {
        if (clients.containsKey(client.getName())) {
            throw new ClientExistsException(client.getName());
        }

        clients.put(client.getName(), client);

        // Calling listener
        for(ClientRegistrationListener l : listeners) {
            l.onClientAdded(client);
        }
        debugListener.printInfo(client);
    }

    private static class DebugListener implements Serializable {
        void printInfo(Client client) {
            System.out.println(client.getName() + " " + new Date());
        }
    }

    private class EmailNotificationListener implements ClientRegistrationListener, Serializable {
        @Override
        public void onClientAdded(Client client) {
            emailService.sendNotificationEmail(client, client.getName()+ "@bank.com");
//            System.out.println("=========================");
//            System.out.println("Notification email for client " + client.getName() + " to be sent");
        }
    }

    private static class PrintClientListener implements ClientRegistrationListener, Serializable {
        @Override
        public void onClientAdded(Client client) {
            System.out.println(client);
        }
    }

    public String getClientsInfo() {
        StringBuffer stringBuffer = new StringBuffer();
        for (Client c: this.getClients()) {
            stringBuffer.append(c.toString());
        }
        System.out.println(stringBuffer);
        return stringBuffer.toString();
    }

    public void closeEmailService() {
        emailService.close();
    }
}
